package com.zhou.org.service.impl;

import com.zhou.framework.config.PasswordPolicyConfig;
import com.zhou.framework.constant.CacheKeyEnum;
import com.zhou.framework.exception.CaptchaException;
import com.zhou.framework.exception.LoginException;
import com.zhou.framework.exception.UserLockException;
import com.zhou.framework.redis.util.RedisUtil;
import com.zhou.framework.util.SessionUtil;
import com.zhou.org.common.PasswordUtil;
import com.zhou.org.dao.User;
import com.zhou.org.dto.LoginRequest;
import com.zhou.org.model.LoginResult;
import com.zhou.org.service.LoginService;
import com.zhou.org.service.OrgService;
import com.zhou.org.service.UserService;
import com.zhou.util.Md5Util;
import com.zhou.util.StringTool;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author lang.zhou
 * @since 2023/2/4
 */
@Slf4j
@Service
public class LoginServiceImpl implements LoginService {

    @Autowired
    private UserService userService;
    @Autowired
    private OrgService orgService;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    public LoginResult login(LoginRequest r) {
        String token = SessionUtil.getCurrentToken();

        User user = this.validateUserStatus(r.getUsername());
        if(!SessionUtil.isLogin()){
            this.validateCaptcha(r);
            //String pubKey = SettingUtil.getStringValue("SYSTEM", "pub_key","");
            //解密后的真实密码
            String pwd = PasswordUtil.decrypt(r.getPassword());
            this.loginLocal(user,pwd);

            token = SessionUtil.login(user);
        }
        return new LoginResult(token,user);
    }

    /**
     * 本地登录
     */
    private void loginLocal(User user,String password){
        if(user == null){
            throw new LoginException("用户名或密码错误");
        }
        String hex = Md5Util.hex(password, user.getSalt());
        if(!Objects.equals(hex,user.getPassword())){
            throw new LoginException("用户名或密码错误");
        }
    }

    /**
     * 判断用户是否被锁定
     */
    private User validateUserStatus(String userName){
        PasswordPolicyConfig instance = PasswordPolicyConfig.getInstance();
        if(instance.isEnable()){
            //redisUtil.redisTemplate.boundValueOps(CacheKeyEnum.PASSWORD_ERROR_COUNT + "||" + userName).get(0,-1);
            String key = CacheKeyEnum.PASSWORD_ERROR_COUNT + "||" + userName;
            int errorCount = instance.getPasswordMaxErrorCount();
            Long n = redisUtil.incrNow(key);
            if(n != null && n.intValue() > errorCount){
                throw new UserLockException();
            }
        }
        User user = userService.getByUserName(userName);
        if(user != null){
            if(Objects.equals(user.getLocked(),1)){
                throw new UserLockException("用户被锁定");
            }
        }
        return user;
    }

    private void validateCaptcha(LoginRequest request){
        if(PasswordPolicyConfig.getInstance().isCaptchaEnable()){
            String verifyKey = CacheKeyEnum.CAPTCHA_CODE_KEY + StringTool.safeToString(request.getUuid(), "");
            String captcha = redisUtil.get(verifyKey);
            redisUtil.del(verifyKey);

            if (StringTool.isBlank(captcha) || !captcha.equalsIgnoreCase(request.getCode())) {
                throw new CaptchaException();
            }
        }
    }
}
